About 7359 letters

About 37 minutes

#Qt Theme - A Pure QSS Qt Theme

Source code: https://github.com/hubenchang0515/QtTheme/

Qt Theme Interface Preview

Qt Theme is a pure QSS-based Qt theme project that allows you to easily improve the styling of existing projects.

It supports C++, PyQt5, PyQt6, PySide2, PySide6, and is also published as WebAssembly on GitHub Pages.

#Installation

Here is a demonstration of usage in Python. First, install it:

pip install QtTheme

#Demo

#Native Style and Code

Let Deep Seek randomly generate a simple interface example for me:

deepseek example code

import sys from PySide6.QtWidgets import * from PySide6.QtGui import QPixmap from PySide6.QtCore import Qt, QTimer class DemoWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("PyQt Widget Demo Interface") self.setGeometry(100, 100, 800, 600) # Create central widget and main layout central_widget = QWidget() self.setCentralWidget(central_widget) main_layout = QVBoxLayout(central_widget) # Add functional sections self.create_input_section(main_layout) self.create_selection_section(main_layout) self.create_display_section(main_layout) self.create_progress_section(main_layout) # Add status bar self.statusBar().showMessage("Ready") # Initialize progress value self.progress_value = 0 self.update_progress() def create_input_section(self, layout): group = QGroupBox("Input Controls") grid = QGridLayout() # Single line text input self.line_edit = QLineEdit() self.line_edit.setPlaceholderText("Single line text input...") grid.addWidget(QLabel("Single Line Text:"), 0, 0) grid.addWidget(self.line_edit, 0, 1) # Multi-line text input self.text_edit = QTextEdit() self.text_edit.setPlaceholderText("Multi-line text input...") grid.addWidget(QLabel("Multi-line Text:"), 1, 0) grid.addWidget(self.text_edit, 1, 1) # Number input self.spin_box = QSpinBox() self.spin_box.setRange(0, 100) grid.addWidget(QLabel("Number Input:"), 2, 0) grid.addWidget(self.spin_box, 2, 1) group.setLayout(grid) layout.addWidget(group) def create_selection_section(self, layout): group = QGroupBox("Selection Controls") hbox = QHBoxLayout() # Checkboxes vbox = QVBoxLayout() self.check1 = QCheckBox("Option 1") self.check2 = QCheckBox("Option 2") vbox.addWidget(self.check1) vbox.addWidget(self.check2) hbox.addLayout(vbox) # Radio buttons vbox = QVBoxLayout() self.radio1 = QRadioButton("Radio 1") self.radio2 = QRadioButton("Radio 2") self.radio1.setChecked(True) vbox.addWidget(self.radio1) vbox.addWidget(self.radio2) hbox.addLayout(vbox) # Combo box self.combo = QComboBox() self.combo.addItems(["Option A", "Option B", "Option C"]) hbox.addWidget(self.combo) group.setLayout(hbox) layout.addWidget(group) def create_display_section(self, layout): group = QGroupBox("Display Controls") hbox = QHBoxLayout() # Label self.label = QLabel("This is a label") self.label.setAlignment(Qt.AlignCenter) self.label.setStyleSheet("border: 1px solid gray; padding: 10px;") hbox.addWidget(self.label) # Image display pixmap = QPixmap(100, 50) pixmap.fill(Qt.blue) image_label = QLabel() image_label.setPixmap(pixmap) hbox.addWidget(image_label) # List widget self.list_widget = QListWidget() self.list_widget.addItems(["Item 1", "Item 2", "Item 3"]) hbox.addWidget(self.list_widget) group.setLayout(hbox) layout.addWidget(group) def create_progress_section(self, layout): group = QGroupBox("Progress Controls") vbox = QVBoxLayout() # Progress bar self.progress_bar = QProgressBar() self.progress_bar.setValue(0) vbox.addWidget(self.progress_bar) # Slider self.slider = QSlider(Qt.Horizontal) self.slider.setRange(0, 100) self.slider.valueChanged.connect(self.on_slider_changed) vbox.addWidget(self.slider) # Control buttons btn_layout = QHBoxLayout() self.start_btn = QPushButton("Start Progress") self.start_btn.clicked.connect(self.start_progress) self.reset_btn = QPushButton("Reset") self.reset_btn.clicked.connect(self.reset_progress) btn_layout.addWidget(self.start_btn) btn_layout.addWidget(self.reset_btn) vbox.addLayout(btn_layout) group.setLayout(vbox) layout.addWidget(group) def on_slider_changed(self, value): self.progress_bar.setValue(value) self.statusBar().showMessage(f"Slider Value: {value}") def start_progress(self): self.timer = QTimer() self.timer.timeout.connect(self.update_progress) self.timer.start(100) def update_progress(self): self.progress_value += 1 if self.progress_value > 100: self.timer.stop() return self.progress_bar.setValue(self.progress_value) self.slider.setValue(self.progress_value) def reset_progress(self): self.progress_value = 0 self.progress_bar.setValue(0) self.slider.setValue(0) if __name__ == "__main__": app = QApplication(sys.argv) window = DemoWindow() window.show() sys.exit(app.exec())

Run it and see:

Native interface style

#Setting Global Style

Import QtTheme and apply the style:

import QtTheme.PySide6 as QtTheme class DemoWindow(QMainWindow): def __init__(self): # omitted... # Set global stylesheet self.setStyleSheet(QtTheme.getThemeStyle('Flat', 'Dark', 'Blue', 'Pink'))

Global dark style

#Setting Colors

Finally, set colors on widgets as needed via QWidget.setProperty:

def create_progress_section(self, layout): # omitted... # Set colors for buttons self.start_btn.setProperty("Color", "Primary") self.reset_btn.setProperty("Color", "Danger")

After setting colors

#Exporting Resources

You can also skip installing QtTheme and export resources via the online page, then include them in your project using RCC:

pyside6-rcc -o resource.py QtTheme.qrc

Just modify the import style, keep other code unchanged:

from PySide6.QtCore import QFile import resource # import the generated resource.py class DemoWindow(QMainWindow): def __init__(self): # omitted... qss = QFile(":/QtTheme/theme/Flat/Dark/Blue/Pink.qss") qss.open(QFile.OpenModeFlag.ReadOnly) self.setStyleSheet(qss.readAll().data().decode())

Created in 5/15/2025

Updated in 5/15/2025